package engine;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import com.threed.jpct.Logger;
import com.threed.jpct.SimpleVector;

public class UniverseFactory {

	public static Universe createFromFile(String filePath) {
		try {
			String line;
			String[] properties = null;
			BufferedReader in = new BufferedReader(new FileReader(filePath));
			Logger.log("Loading map file: " + filePath);
			Universe universe = new Universe();
			while ((line = in.readLine()) != null) {
				properties = line.split("\\s");

				Planet planet = new Planet();
				planet.setPosition(Float.parseFloat(properties[0]), Float.parseFloat(properties[1]), Float.parseFloat(properties[2]));
				planet.setRadius(Float.parseFloat(properties[3]));
				planet.setPoints(Integer.parseInt(properties[4]));
				if (properties[5].equals("P")) {
					planet.setOwner(Ownership.PLAYER);
				} else if (properties[5].equals("E")) {
					planet.setOwner(Ownership.ENEMY);
				} else if (properties[5].equals("N")) {
					planet.setOwner(Ownership.NEUTRAL);
				}
				universe.addPlanet(planet);
			}
			return universe;
		} catch (NumberFormatException e) {
			Logger.log("Map file contains errors.");
			Logger.log(e.getMessage());
			return null;
		} catch (IOException e) {
			Logger.log("Could not load map file.");
			Logger.log(e.getMessage());
			return null;
		}
	}

	public static Universe createRandom(int numberOfPlanets) {
		float minDistance = 10.0f;
		float maxDistance = 60.0f;

		float minRadius = 1.5f;
		float maxRadius = 8.0f;

		int minPoints = 1;
		int maxPoints = 40;

		Universe universe = new Universe();
		List<Planet> planets = new ArrayList<Planet>();

		for (int i = 0; i < numberOfPlanets; i++) {
			Planet planet = new Planet();
			planet.setPosition(new SimpleVector(random(minDistance, maxDistance, true), random(minDistance, maxDistance, true), random(minDistance, maxDistance, true)));
			planet.setRadius(random(minRadius, maxRadius, false));
			planet.setPoints((int) random(minPoints, maxPoints, false));
			planet.setOwner(Ownership.NEUTRAL);

			if (planetColides(planet, planets)) {
				i--;
				continue;
			}

			planets.add(planet);
		}

		planets.get(0).setOwner(Ownership.PLAYER);
		planets.get(0).setPoints(50);
		planets.get(1).setOwner(Ownership.ENEMY);
		planets.get(1).setPoints(50);
		
		universe.getPlanets().addAll(planets);

		return universe;
	}

	private static Random RANDOM = new Random(System.nanoTime());

	private static final float random(final float pMin, final float pMax, boolean randomSign) {
		float number = pMin + RANDOM.nextFloat() * (pMax - pMin);
		if (randomSign) {
			if (-1 + (RANDOM.nextFloat() * (1 + 1)) < 0)
				return -number;
		}
		return number;
	}

	private static boolean planetColides(Planet p, List<Planet> otherPlanets) {
		for (Planet o : otherPlanets) {
			if (p.getPosition().distance(o.getPosition()) < p.getRadius() + 2 * o.getRadius())
				return true;
		}
		return false;
	}
}
